﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SimpleRest.Core.Routing;
using SimpleRest.WebTest.Services;
using SimpleRest.Core.Extensions;
using SimpleRest.Core;

namespace SimpleRest.Tests.Routing
{
    [TestClass]
    public class MockProductOperationInvokingTests
    {
        [TestMethod]
        public void PASS_Pipeline_Given_ProductServiceType_GetAll_ReturnXml()
        {
            Pipeline pipeline = new Pipeline(typeof(MockProductsService));

            Configuration httpConfiguration = ConfigurationFactory.CreateConfiguration();

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = null;
            request.Cookies = null;
            request.Headers = new List<Header>()
            {
                new Header("accept", "text/xml")
            };
            var requestMediaTypeFormatter = Pipeline.GetRequestMediaTypeFormatter(request, httpConfiguration);
            var responseMediaTypeFormatter = Pipeline.GetResponseMediaTypeFormatter(request, httpConfiguration);
            Assert.IsTrue(requestMediaTypeFormatter != null && responseMediaTypeFormatter != null);
           
            request.Uri = "http://localhost/products";
            request.UserHostAddress = "127.0.0.1";
            request.Verb = "GET";

            request.RouteInformation = new RouteInformation("products");
            request.RouteInformation.RouteData = null;

            var response = pipeline.ExecuteOperation(request, httpConfiguration);
            Console.WriteLine("Status Code: " + response.StatusCode.ToString());

            if (response != null && response.Content != null)
            {
                var responseStream = responseMediaTypeFormatter.Serialize(response.Content);
                var responseBytes = HelperUtility.ReadToEnd(responseStream);
                var responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
                Console.WriteLine(responseText);
            }
            Assert.IsTrue(response.Content != null && response.StatusCode == System.Net.HttpStatusCode.OK);
        }

        [TestMethod]
        public void PASS_Pipeline_Given_ProductService_GetAll_ReturnXml()
        {
            MockProductsService svc = new MockProductsService();

            Pipeline pipeline = new Pipeline(svc);

            Configuration httpConfiguration = ConfigurationFactory.CreateConfiguration();

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = null;
            request.Cookies = null;
            request.Headers = new List<Header>()
            {
                new Header("accept", "text/xml"),
                new Header("content-type", "text/xml")
            };
            var requestMediaTypeFormatter = Pipeline.GetRequestMediaTypeFormatter(request, httpConfiguration);
            var responseMediaTypeFormatter = Pipeline.GetResponseMediaTypeFormatter(request, httpConfiguration);
            Assert.IsTrue(requestMediaTypeFormatter != null && responseMediaTypeFormatter != null);

            request.Uri = "http://localhost/products";
            request.UserHostAddress = "127.0.0.1";
            request.Verb = "GET";

            request.RouteInformation = new RouteInformation("products");
            request.RouteInformation.RouteData = null;

            var response = pipeline.ExecuteOperation(request, httpConfiguration);
            Console.WriteLine("Status Code: " + response.StatusCode.ToString());

            if (response != null && response.Content != null)
            {
                var responseStream = responseMediaTypeFormatter.Serialize(response.Content);
                var responseBytes = HelperUtility.ReadToEnd(responseStream);
                var responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
                Console.WriteLine(responseText);
            }
            Assert.IsTrue(response.Content != null && response.StatusCode == System.Net.HttpStatusCode.OK);
        }

        [TestMethod]
        public void PASS_Pipeline_Given_ProductServiceType_GetAll_ReturnJson()
        {
            Pipeline pipeline = new Pipeline(typeof(MockProductsService));

            Configuration httpConfiguration = ConfigurationFactory.CreateConfiguration();

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = null;
            request.Cookies = null;
            request.Headers = new List<Header>()
            {
                new Header("accept", "application/json")
            };
            var requestMediaTypeFormatter = Pipeline.GetRequestMediaTypeFormatter(request, httpConfiguration);
            var responseMediaTypeFormatter = Pipeline.GetResponseMediaTypeFormatter(request, httpConfiguration);
            Assert.IsTrue(requestMediaTypeFormatter != null && responseMediaTypeFormatter != null);

            request.Uri = "http://localhost/products";
            request.UserHostAddress = "127.0.0.1";
            request.Verb = "GET";

            request.RouteInformation = new RouteInformation("products");
            request.RouteInformation.RouteData= null;

            var response = pipeline.ExecuteOperation(request, httpConfiguration);
            Console.WriteLine("Status Code: " + response.StatusCode.ToString());

            if (response != null && response.Content != null)
            {
                var responseStream = responseMediaTypeFormatter.Serialize(response.Content);
                var responseBytes = HelperUtility.ReadToEnd(responseStream);
                var responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
                Console.WriteLine(responseText);
            }
            Assert.IsTrue(response.Content != null && response.StatusCode == System.Net.HttpStatusCode.OK);
        }

        [TestMethod]
        public void PASS_Pipeline_Given_ProductServiceType_GetOne_ReturnXml()
        {
            Pipeline pipeline = new Pipeline(typeof(MockProductsService));

            Configuration httpConfiguration = ConfigurationFactory.CreateConfiguration();

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = null;
            request.Cookies = null;
            request.Headers = new List<Header>()
            {
                new Header("accept", "text/xml")
            };
            // request.RouteValues = null;
            request.Uri = "http://localhost/products";
            request.UserHostAddress = "127.0.0.1";
            request.Verb = "GET";

            request.RouteInformation = new RouteInformation("/products/{id}/");
            request.RouteInformation.RouteData= new Dictionary<string, object>()
            {
               { "id", 1 }
            };
            var requestMediaTypeFormatter = Pipeline.GetRequestMediaTypeFormatter(request, httpConfiguration);
            var responseMediaTypeFormatter = Pipeline.GetResponseMediaTypeFormatter(request, httpConfiguration);
            Assert.IsTrue(requestMediaTypeFormatter != null && responseMediaTypeFormatter != null);

            var response = pipeline.ExecuteOperation(request, httpConfiguration);
            Console.WriteLine("Status Code: " + response.StatusCode.ToString());

            if (response != null && response.Content != null)
            {
                var responseStream = responseMediaTypeFormatter.Serialize(response.Content);
                var responseBytes = HelperUtility.ReadToEnd(responseStream);
                var responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
                Console.WriteLine(responseText);
            }

            Assert.IsTrue(response.Content != null && response.StatusCode == System.Net.HttpStatusCode.OK);
        }

        [TestMethod]
        public void PASS_Pipeline_Given_ProductServiceType_GetOne_ReturnJson()
        {
            Pipeline pipeline = new Pipeline(typeof(MockProductsService));

            Configuration httpConfiguration = ConfigurationFactory.CreateConfiguration();

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = null;
            request.Cookies = null;
            request.Headers = new List<Header>()
            {
                new Header("accept", "application/json")
            };
            // request.RouteValues = null;
            request.Uri = "http://localhost/products";
            request.UserHostAddress = "127.0.0.1";
            request.Verb = "GET";

            request.RouteInformation = new RouteInformation("/products/{id}/");
            request.RouteInformation.RouteData= new Dictionary<string, object>()
            {
               { "id", 1 }
            };
            var requestMediaTypeFormatter = Pipeline.GetRequestMediaTypeFormatter(request, httpConfiguration);
            var responseMediaTypeFormatter = Pipeline.GetResponseMediaTypeFormatter(request, httpConfiguration);
            Assert.IsTrue(requestMediaTypeFormatter != null && responseMediaTypeFormatter != null);

            var response = pipeline.ExecuteOperation(request, httpConfiguration);
            Console.WriteLine("Status Code: " + response.StatusCode.ToString());

            if (response != null && response.Content != null)
            {
                var responseStream = responseMediaTypeFormatter.Serialize(response.Content);
                var responseBytes = HelperUtility.ReadToEnd(responseStream);
                var responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
                Console.WriteLine(responseText);
            }
            Assert.IsTrue(response.Content != null && response.StatusCode == System.Net.HttpStatusCode.OK);
        }

        [TestMethod]
        public void PASS_Pipeline_Given_ProductServiceType_GetPrice_ReturnXml()
        {
            Pipeline pipeline = new Pipeline(typeof(MockProductsService));

            Configuration httpConfiguration = ConfigurationFactory.CreateConfiguration();

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = null;
            request.Cookies = null;
            request.Headers = new List<Header>()
            {
                new Header("accept", "text/xml")
            };
            // request.RouteValues = null;
            request.Uri = "http://localhost/products";
            request.UserHostAddress = "127.0.0.1";
            request.Verb = "GET";

            request.RouteInformation = new RouteInformation("/products/{id}/Price");
            request.RouteInformation.RouteData= new Dictionary<string, object>()
            {
               { "id", 1 }
            };
            var requestMediaTypeFormatter = Pipeline.GetRequestMediaTypeFormatter(request, httpConfiguration);
            var responseMediaTypeFormatter = Pipeline.GetResponseMediaTypeFormatter(request, httpConfiguration);
            Assert.IsTrue(requestMediaTypeFormatter != null && responseMediaTypeFormatter != null);

            var response = pipeline.ExecuteOperation(request, httpConfiguration);
            Console.WriteLine("Status Code: " + response.StatusCode.ToString());

            if (response != null && response.Content != null)
            {
                var responseStream = responseMediaTypeFormatter.Serialize(response.Content);
                var responseBytes = HelperUtility.ReadToEnd(responseStream);
                var responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
                Console.WriteLine(responseText);
            }
            Assert.IsTrue(response.Content != null && response.StatusCode == System.Net.HttpStatusCode.OK);
        }

        [TestMethod]
        public void PASS_Pipeline_Given_ProductServiceType_GetPrice_ReturnJson()
        {
            Pipeline pipeline = new Pipeline(typeof(MockProductsService));

            Configuration httpConfiguration = ConfigurationFactory.CreateConfiguration();

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = null;
            request.Cookies = null;
            request.Headers = new List<Header>()
            {
                new Header("accept", "application/json")
            };
            // request.RouteValues = null;
            request.Uri = "http://localhost/products";
            request.UserHostAddress = "127.0.0.1";
            request.Verb = "GET";

            request.RouteInformation = new RouteInformation("/products/{id}/Price");
            request.RouteInformation.RouteData= new Dictionary<string, object>()
            {
               { "id", 1 }
            };
            var requestMediaTypeFormatter = Pipeline.GetRequestMediaTypeFormatter(request, httpConfiguration);
            var responseMediaTypeFormatter = Pipeline.GetResponseMediaTypeFormatter(request, httpConfiguration);
            Assert.IsTrue(requestMediaTypeFormatter != null && responseMediaTypeFormatter != null);

            var response = pipeline.ExecuteOperation(request, httpConfiguration);
            Console.WriteLine("Status Code: " + response.StatusCode.ToString());

            if (response != null && response.Content != null)
            {
                var responseStream = responseMediaTypeFormatter.Serialize(response.Content);
                var responseBytes = HelperUtility.ReadToEnd(responseStream);
                var responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
                Console.WriteLine(responseText);
            }
            Assert.IsTrue(response.Content != null && response.StatusCode == System.Net.HttpStatusCode.OK);
        }

        [TestMethod]
        public void PASS_Pipeline_Given_ProductServiceType_GetContent_ReturnXml()
        {
            Pipeline pipeline = new Pipeline(typeof(MockProductsService));

            Configuration httpConfiguration = ConfigurationFactory.CreateConfiguration();

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = null;
            request.Cookies = null;
            request.Headers = new List<Header>()
            {
                new Header("accept", "text/xml")
            };
            // request.RouteValues = null;
            request.Uri = "http://localhost/products";
            request.UserHostAddress = "127.0.0.1";
            request.Verb = "GET";

            request.RouteInformation = new RouteInformation("/products/{id}/Content");
            request.RouteInformation.RouteData= new Dictionary<string, object>()
            {
               { "id", 1 }
            };
            var requestMediaTypeFormatter = Pipeline.GetRequestMediaTypeFormatter(request, httpConfiguration);
            var responseMediaTypeFormatter = Pipeline.GetResponseMediaTypeFormatter(request, httpConfiguration);
            Assert.IsTrue(requestMediaTypeFormatter != null && responseMediaTypeFormatter != null);

            var response = pipeline.ExecuteOperation(request, httpConfiguration);
            Console.WriteLine("Status Code: " + response.StatusCode.ToString());

            if (response != null && response.Content != null)
            {
                var responseStream = responseMediaTypeFormatter.Serialize(response.Content);
                var responseBytes = HelperUtility.ReadToEnd(responseStream);
                var responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
                Console.WriteLine(responseText);
            }
            Assert.IsTrue(response.Content != null && response.StatusCode == System.Net.HttpStatusCode.OK);
        }

        [TestMethod]
        public void PASS_Pipeline_Given_ProductServiceType_GetContent_ReturnJson()
        {
            Pipeline pipeline = new Pipeline(typeof(MockProductsService));

            Configuration httpConfiguration = ConfigurationFactory.CreateConfiguration();

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = null;
            request.Cookies = null;
            request.Headers = new List<Header>()
            {
                new Header("accept", "application/json")
            };
            // request.RouteValues = null;
            request.Uri = "http://localhost/products";
            request.UserHostAddress = "127.0.0.1";
            request.Verb = "GET";

            request.RouteInformation = new RouteInformation("/products/{id}/Content");
            request.RouteInformation.RouteData= new Dictionary<string, object>()
            {
               { "id", 1 }
            };
            var requestMediaTypeFormatter = Pipeline.GetRequestMediaTypeFormatter(request, httpConfiguration);
            var responseMediaTypeFormatter = Pipeline.GetResponseMediaTypeFormatter(request, httpConfiguration);
            Assert.IsTrue(requestMediaTypeFormatter != null && responseMediaTypeFormatter != null);

            var response = pipeline.ExecuteOperation(request, httpConfiguration);
            Console.WriteLine("Status Code: " + response.StatusCode.ToString());

            if (response != null && response.Content != null)
            {
                var responseStream = responseMediaTypeFormatter.Serialize(response.Content);
                var responseBytes = HelperUtility.ReadToEnd(responseStream);
                var responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
                Console.WriteLine(responseText);
            }
            Assert.IsTrue(response.Content != null && response.StatusCode == System.Net.HttpStatusCode.OK);
        }

        [TestMethod]
        public void PASS_Pipeline_Given_ProductServiceType_DeleteOne_ReturnXml()
        {
            Pipeline pipeline = new Pipeline(typeof(MockProductsService));

            Configuration httpConfiguration = ConfigurationFactory.CreateConfiguration();

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = null;
            request.Cookies = null;
            request.Headers = new List<Header>()
            {
                new Header("accept", "text/xml")
            };
            // request.RouteValues = null;
            request.Uri = "http://localhost/products";
            request.UserHostAddress = "127.0.0.1";
            request.Verb = "DELETE";

            request.RouteInformation = new RouteInformation("/products/{id}/");
            request.RouteInformation.RouteData= new Dictionary<string, object>()
            {
               { "id", 1}
            };
            var requestMediaTypeFormatter = Pipeline.GetRequestMediaTypeFormatter(request, httpConfiguration);
            var responseMediaTypeFormatter = Pipeline.GetResponseMediaTypeFormatter(request, httpConfiguration);
            Assert.IsTrue(requestMediaTypeFormatter != null && responseMediaTypeFormatter != null);

            var response = pipeline.ExecuteOperation(request, httpConfiguration);
            Console.WriteLine("Status Code: " + response.StatusCode.ToString());

            if (response != null && response.Content != null)
            {
                var responseStream = responseMediaTypeFormatter.Serialize(response.Content);
                var responseBytes = HelperUtility.ReadToEnd(responseStream);
                var responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
                Console.WriteLine(responseText);
            }
            Assert.IsTrue(response.StatusCode == System.Net.HttpStatusCode.OK);
        }

        [TestMethod]
        public void PASS_Pipeline_Given_ProductServiceType_DeleteOne_ReturnJson()
        {
            Pipeline pipeline = new Pipeline(typeof(MockProductsService));

            Configuration httpConfiguration = ConfigurationFactory.CreateConfiguration();

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = null;
            request.Cookies = null;
            request.Headers = new List<Header>()
            {
                new Header("accept", "application/json")
            };
            // request.RouteValues = null;
            request.Uri = "http://localhost/products";
            request.UserHostAddress = "127.0.0.1";
            request.Verb = "DELETE";

            request.RouteInformation = new RouteInformation("/products/{id}/");
            request.RouteInformation.RouteData= new Dictionary<string, object>()
            {
               { "id", 1 }
            };
            var requestMediaTypeFormatter = Pipeline.GetRequestMediaTypeFormatter(request, httpConfiguration);
            var responseMediaTypeFormatter = Pipeline.GetResponseMediaTypeFormatter(request, httpConfiguration);
            Assert.IsTrue(requestMediaTypeFormatter != null && responseMediaTypeFormatter != null);

            var response = pipeline.ExecuteOperation(request, httpConfiguration);
            Console.WriteLine("Status Code: " + response.StatusCode.ToString());

            if (response != null && response.Content != null)
            {
                var responseStream = responseMediaTypeFormatter.Serialize(response.Content);
                var responseBytes = HelperUtility.ReadToEnd(responseStream);
                var responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
                Console.WriteLine(responseText);
            }
            Assert.IsTrue(response.StatusCode == System.Net.HttpStatusCode.OK);
        }

        [TestMethod]
        public void PASS_Pipeline_Given_ProductServiceType_CreateOne_ReturnXml()
        {
            Pipeline pipeline = new Pipeline(typeof(MockProductsService));

            Configuration httpConfiguration = ConfigurationFactory.CreateConfiguration();

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = null;
            request.Cookies = null;
            request.Headers = new List<Header>()
            {
                new Header("accept", "text/xml"),
                new Header("content-type", "text/xml")
            };
            // request.RouteValues = null;
            request.Uri = "http://localhost/products";
            request.UserHostAddress = "127.0.0.1";
            request.Verb = "POST";

            request.RouteInformation = new RouteInformation("/products/");
            request.RouteInformation.RouteData= new Dictionary<string, object>();
            var requestMediaTypeFormatter = Pipeline.GetRequestMediaTypeFormatter(request, httpConfiguration);
            var responseMediaTypeFormatter = Pipeline.GetResponseMediaTypeFormatter(request, httpConfiguration);
            Assert.IsTrue(requestMediaTypeFormatter != null && responseMediaTypeFormatter != null);

            string id = Guid.NewGuid().ToString();
            request.Content = requestMediaTypeFormatter.Serialize(new Product()
            {
                Id = id,
                Name = "Test Product",
                Content = new Content()
                {
                    Description = "Test Product Description Here!  Some super loon description...",
                    ShortDescription = "Test Product Description",
                    ImageUris = new List<string>()
                    {
                        "http://www.google.com/images/xaw.jpg",
                        "http://www.google.com/images/xa234w.jpg",
                        "http://www.google.com/images/xadf2fw.jpg"
                    }
                }
            });

            var response = pipeline.ExecuteOperation(request, httpConfiguration);
            Console.WriteLine("Status Code: " + response.StatusCode.ToString());

            if (response != null && response.Content != null)
            {
                var responseStream = responseMediaTypeFormatter.Serialize(response.Content);
                var responseBytes = HelperUtility.ReadToEnd(responseStream);
                var responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
                Console.WriteLine(responseText);
            }
            Assert.IsTrue(response.StatusCode == System.Net.HttpStatusCode.Created);
        }

        [TestMethod]
        public void PASS_Pipeline_Given_ProductServiceType_CreateOne_ReturnJson()
        {
            Pipeline pipeline = new Pipeline(typeof(MockProductsService));

            Configuration httpConfiguration = ConfigurationFactory.CreateConfiguration();

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = null;
            request.Cookies = null;
            request.Headers = new List<Header>()
            {
                new Header("accept", "application/json"),
                new Header("content-type", "application/json")
            };
            // request.RouteValues = null;
            request.Uri = "http://localhost/products";
            request.UserHostAddress = "127.0.0.1";
            request.Verb = "POST";

            request.RouteInformation = new RouteInformation("/products/");
            request.RouteInformation.RouteData= new Dictionary<string, object>();
            var requestMediaTypeFormatter = Pipeline.GetRequestMediaTypeFormatter(request, httpConfiguration);
            var responseMediaTypeFormatter = Pipeline.GetResponseMediaTypeFormatter(request, httpConfiguration);
            Assert.IsTrue(requestMediaTypeFormatter != null && responseMediaTypeFormatter != null);

            string id = Guid.NewGuid().ToString();
            request.Content = requestMediaTypeFormatter.Serialize(new Product()
            {
                Id = id,
                Name = "Test Product",
                Content = new Content()
                {
                    Description = "Test Product Description Here!  Some super loon description...",
                    ShortDescription = "Test Product Description",
                    ImageUris = new List<string>()
                    {
                        "http://www.google.com/images/xaw.jpg",
                        "http://www.google.com/images/xa234w.jpg",
                        "http://www.google.com/images/xadf2fw.jpg"
                    }
                }
            });

            var response = pipeline.ExecuteOperation(request, httpConfiguration);
            Console.WriteLine("Status Code: " + response.StatusCode.ToString());

            if (response != null && response.Content != null)
            {
                var responseStream = responseMediaTypeFormatter.Serialize(response.Content);
                var responseBytes = HelperUtility.ReadToEnd(responseStream);
                var responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
                Console.WriteLine(responseText);
            }
            Assert.IsTrue(response.StatusCode == System.Net.HttpStatusCode.Created);
        }
    }
}
